home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / origami / loop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  41.9 KB  |  1,486 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #ifdef CONFIG_H
  4. #   include "config.h"
  5. #endif
  6.  
  7. #include <sys/types.h>
  8. #ifndef NO_MAIL
  9. #  ifndef USEGETHOSTNAME
  10. #     include <sys/utsname.h>
  11. #  else
  12. #     define utsname { char nodename[1024]; }
  13. #     define uname(x) gethostname(&((x)->nodename),1023)
  14. #  endif
  15. #endif
  16. #include <pwd.h>
  17. #include <unistd.h>
  18. #include <limits.h>
  19. #include <signal.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23.  
  24. #define LOOP_C
  25. #define I_BUFFLOOP_C
  26. #define I_DISPLAY_C
  27. #define I_FOLDFILING_C
  28. #define I_FOLDHELP_C
  29. #define I_FOLDING_C
  30. #define I_FINDS_C
  31. #define I_GETMSG_C
  32. #define I_GETTK_C
  33. #define I_KEYBOARD_C
  34. #define I_MAIN_C
  35. #define I_MISC_C
  36. #define I_MESSAGES_C
  37. #define I_ORIEDT_C
  38. #define I_PROMPT_C
  39. #define I_READFOLDS_C
  40. #define I_SCREEN_C
  41. #define I_SIGNALS_C
  42. #define I_VIRTUAL_C
  43.  
  44. #include "origami.h"
  45. #include <h/envvar_str.h>
  46. #include <lib/ori_add_lib.h>
  47. /*}}}  */
  48.  
  49. /*{{{  variables*/
  50. public unsigned char line_buffer[LINELEN + 1];
  51. public FILE *start_pipe=0;
  52. public boolean running=False;
  53. public buffer_data init_buffer=
  54.  {
  55.    /*{{{  screen data*/
  56.    { 0,      /* no */
  57.      0,      /* id */
  58.      /*{{{  off set*/
  59.      { 0,    /* w */
  60.        0     /* h */
  61.      },
  62.      /*}}}  */
  63.      /*{{{  win dow size*/
  64.      { 0,    /* w */
  65.        0     /* h */
  66.      },
  67.      /*}}}  */
  68.      True,   /* clreol */
  69.      True,   /* bold_stat */
  70.      /*{{{  txt_size*/
  71.      { 0,    /* w */
  72.        0     /* h */
  73.      },
  74.      /*}}}  */
  75.      0,      /* start */
  76.      0,      /* end */
  77.      /*{{{  cursor positions*/
  78.      { 0,    /* w */
  79.        0     /* h */
  80.      },
  81.      /*}}}  */
  82.      1,      /* shift_w_size */
  83.      0,      /* shift_w_offset */
  84.      0,      /* screen_shift_w_offset */
  85.      1       /* end_level */
  86. #   ifdef MULTIPLE_SCREEN
  87.         MULT_SCR_INIT
  88. #   endif
  89.    },
  90.    /*}}}  */
  91.    /*{{{  fold data*/
  92.    { { { END_STANDARD, FILE_STANDARD, LINE_STANDARD, BEGIN_STANDARD },
  93.        FOLD_TAG_LENGTH,
  94.        FOLD_TAG_LENGTH,
  95.      },      /* fold marks */
  96.      False,  /* count_comment_line */
  97.      0,      /* entered */
  98.      0,      /* enter_spaces */
  99.      0,      /* real_head */
  100.      0,      /* real_tail */
  101.      0,      /* head */
  102.      0,      /* tail */
  103.      0,      /* End_of_fold */
  104.      0,      /* Start_of_fold */
  105.      0,      /* Line_after_fold */
  106.      0,      /* current */
  107.      NOT_FOLD,
  108.              /* cur_line_typ */
  109.      0       /* select_ptr */
  110.    },
  111.    /*}}}  */
  112.    /*{{{  editing*/
  113.    { 0,      /* first_edit_pos */
  114.      0,      /* pre_edit_pos */
  115.      0,      /* part_line */
  116.      False,  /* split_line */
  117.      False,  /* fold_in */
  118.      0,      /* file_no */
  119.      0,      /* makefold_indent */
  120.    },
  121.    /*}}}  */
  122.    /*{{{  mode data*/
  123.    { no_selection,
  124.      True,   /* last display used not selection */
  125.      False,  /* select_mode */
  126.      False,  /* full_shift */
  127.      False,  /* hash_shift */
  128.      False,  /* overwrite */
  129.      False,  /* read_only */
  130.      False,  /* user_view */
  131.      unchanged_file,
  132.              /* file_changed_status */
  133.      False,  /* dir_edit */
  134.      { F_C_NONE,   /* dialect */
  135.        { 0,0 },
  136.              /* length of comments */
  137.        "","" /* empty texts */
  138.      }
  139.    },
  140.    /*}}}  */
  141.    /*{{{  screen modes*/
  142.    { 0,    /* last x position */
  143.      0     /* y position */
  144.    }
  145.    /*}}}  */
  146.  };
  147. public win_data root_dont_use={ 0,0 };
  148. public boolean no_fold_out=False;
  149. public int startup_line=0;
  150. private int buff_id_used=1;
  151. /*}}}  */
  152.  
  153. /*{{{  buffer data*/
  154. private int curr_buff;
  155. private int bd_buffer;
  156. private int dsp_buff;
  157. public int buff_used;
  158.  
  159. public int mult_edit;
  160.  
  161. #define B_L_PAKET 8
  162. private buffer_data **buffer_list;
  163. int b_l_size;
  164.  
  165. public buffer_data bd;
  166. /*}}}  */
  167. /*{{{  warn_mult_edit*/
  168. public void warn_mult_edit(void)
  169. { int search,i,n;
  170.  
  171.   for
  172.    ( n=0,
  173.      i=buff_used-1,
  174.      search=(bd_buffer==curr_buff)
  175.              ? bd.e.file_no
  176.              : buffer_list[curr_buff]->e.file_no
  177.    ; i>=0
  178.    ; i--
  179.    )
  180.      if (i!=curr_buff && buffer_list[i]->e.file_no==search)
  181.         n++;
  182.   ocl_var[var_m_edit].v=(mult_edit=n)+1;
  183. }
  184. /*}}}  */
  185. /*{{{  set_bd*/
  186. private void set_bd(buffer_data const * const b)
  187. {
  188.   bd= *b;
  189.   dialects[F_C_USER].lg=bd.m.dialect.lg;
  190. }
  191. /*}}}  */
  192. /*{{{  save_bd*/
  193. private void save_bd(buffer_data * const b)
  194. {
  195.   bd.m.dialect.lg=dialects[F_C_USER].lg;
  196.   *b=bd;
  197. }
  198. /*}}}  */
  199. /*{{{  window handling*/
  200. /*{{{  constants*/
  201. #define min_scr_height (TXT_MIN_H-var_notitle)
  202. #define min_scr_width  TXT_MIN_W
  203. /*}}}  */
  204. /*{{{  typdef w_op*/
  205. typedef enum
  206.  { resize,
  207.    del,
  208.    h_grow,h_shrink,h_splitt,h_t_splitt,
  209.    w_grow,w_shrink,w_splitt,w_l_splitt
  210.  } w_op;
  211. /*}}}  */
  212. #ifndef MULTIPLE_SCREEN
  213.   /*{{{  type w_type*/
  214.   typedef enum { single,top_down,left_right } w_type;
  215.   /*}}}  */
  216.   /*{{{  type window*/
  217.   typedef struct window
  218.    { win_data s;
  219.      win_data saved_s;
  220.      w_type t;
  221.      union
  222.       { struct { struct window *w1;struct window *w2; } node;
  223.         struct { buffer_data const *b; } edge;
  224.       } dat;
  225.    } window;
  226.   /*}}}  */
  227.   /*{{{  variables*/
  228.   private win_data splitt;
  229.   private win_data root_size;
  230.   private win_data min_cur_size;
  231.   private w_op rec_win_op;
  232.   private buffer_data const *win_buff_arg;
  233.   private window *root_window;
  234.   /*}}}  */
  235.  
  236.   /*{{{  init_root_window_size*/
  237.   private void init_root_window_size(void)
  238.   {
  239.     if ((message_line=screen.h-root_dont_use.h)<=0)
  240.        message_line=1;
  241.     area_line.h=message_line-area_used;
  242.     if (area_line.h<=min_scr_height)
  243.        area_line.h=message_line-1;
  244.     if (area_line.h<=0)
  245.        area_line.h=1;
  246.     if ((area_line.w=root_size.w=screen.w-root_dont_use.w)<=0)
  247.        area_line.w=1;
  248.     if ((root_size.h=(area_used?area_line.h:message_line)-1)<=0)
  249.        root_size.h=1;
  250.   }
  251.   /*}}}  */
  252.   /*{{{  window_op*/
  253.   /*{{{  variables*/
  254.   private win_data add_from_delete;
  255.   /*}}}  */
  256.  
  257.   /*{{{  rec_w_op*/
  258.   private win_data rec_w_op(window*w,win_data s,boolean hs,boolean ws)
  259.   {
  260.     switch (w->t)
  261.      {
  262.        /*{{{  single node=1 window*/
  263.        case single:
  264.           if (w->dat.edge.b==buffer_list[curr_buff])
  265.            { s=w->s;
  266.              /*{{{  handle op*/
  267.              switch(rec_win_op)
  268.               { case h_splitt:
  269.                 case h_t_splitt:
  270.                 case w_splitt:
  271.                 case w_l_splitt:
  272.                  { window *n_tl_win,*n_br_win;
  273.  
  274.                    /*{{{  get new edge's*/
  275.                    if
  276.                     (    !(n_tl_win=ori_malloc(sizeof(window)))
  277.                       || !(n_br_win=ori_malloc(sizeof(window)))
  278.                     )
  279.                       exit_origami(r_mem_full,M_NO_MEMORY);
  280.                    /*}}}  */
  281.                    /*{{{  init some edge data*/
  282.                    *n_tl_win = *w;
  283.                    n_br_win->t=single;
  284.                    n_br_win->dat.edge.b=win_buff_arg;
  285.                    /*}}}  */
  286.                    if (rec_win_op==h_splitt || rec_win_op==h_t_splitt)
  287.                     { splitt.h++;
  288.                       /*{{{  set nodes*/
  289.                       w->t=top_down;
  290.                       if (rec_win_op==h_splitt)
  291.                        { w->dat.node.w1=n_tl_win;
  292.                          w->dat.node.w2=n_br_win;
  293.                        }
  294.                       else
  295.                        { w->dat.node.w1=n_br_win;
  296.                          w->dat.node.w2=n_tl_win;
  297.                        }
  298.                       /*}}}  */
  299.                       /*{{{  set sizes*/
  300.                       n_br_win->saved_s.w=n_br_win->saved_s.h=0;
  301.                       n_br_win->s.w=n_tl_win->s.w;
  302.                       n_tl_win->s.h/=2;
  303.                       n_br_win->s.h=w->s.h-n_tl_win->s.h;
  304.                       /*}}}  */
  305.                       ori_assert(w->s.h==s.h && w->s.w==s.w,"single size splitt top diff in regop");
  306.                       ori_assert(w->s.w==w->dat.node.w1->s.w && w->s.w==w->dat.node.w2->s.w,"single size splitt width diff in regop");
  307.                       ori_assert(w->s.h==w->dat.node.w1->s.h+w->dat.node.w2->s.h,"single size splitt height-sum diff in regop");
  308.                     }
  309.                    else
  310.                     { splitt.w++;
  311.                       /*{{{  set nodes*/
  312.                       w->t=left_right;
  313.                       if (rec_win_op==w_splitt)
  314.                        { w->dat.node.w1=n_tl_win;
  315.                          w->dat.node.w2=n_br_win;
  316.                        }
  317.                       else
  318.                        { w->dat.node.w1=n_br_win;
  319.                          w->dat.node.w2=n_tl_win;
  320.                        }
  321.                       /*}}}  */
  322.                       /*{{{  set sizes*/
  323.                       n_br_win->saved_s.w=n_br_win->saved_s.h=0;
  324.                       n_br_win->s.h=n_tl_win->s.h;
  325.                       n_tl_win->s.w/=2;
  326.                       n_br_win->s.w=w->s.w-n_tl_win->s.w;
  327.                       /*}}}  */
  328.                       ori_assert(w->s.w==s.w && w->s.h==s.h,"single size splitt top diff in regop");
  329.                       ori_assert(w->s.h==w->dat.node.w1->s.h && w->s.h==w->dat.node.w2->s.h,"single size splitt height diff in regop");
  330.                       ori_assert(w->s.w==w->dat.node.w1->s.w+w->dat.node.w2->s.w,"single size splitt width-sum diff in regop");
  331.                     }
  332.                    break;
  333.                  }
  334.                 case h_grow:  s.h++;break;
  335.                 case h_shrink:s.h--;break;
  336.                 case w_grow:  s.w++;break;
  337.                 case w_shrink:s.w--;break;
  338.                 case del:     break;
  339.                 /*{{{  resize, maybe add deleted size*/
  340.                 case resize:
  341.                    s.h+=add_from_delete.h;
  342.                    add_from_delete.h=0;
  343.                    s.w+=add_from_delete.w;
  344.                    add_from_delete.w=0;
  345.                    break;
  346.                 /*}}}  */
  347.               }
  348.              if (rec_win_op!=del)
  349.                 rec_win_op=resize;
  350.              /*}}}  */
  351.              ori_assert(rec_win_op!=del || w->dat.edge.b!=win_buff_arg,"del in single node");
  352.              /*{{{  handle height*/
  353.              if (s.h>root_size.h)
  354.                 s.h=root_size.h;
  355.              else if (s.h<min_cur_size.h)
  356.                 s.h=min_cur_size.h;
  357.              if (!hs && s.h<root_size.h)
  358.                 s.h=root_size.h;
  359.              /*}}}  */
  360.              /*{{{  handle width*/
  361.              if (s.w>root_size.w)
  362.                 s.w=root_size.w;
  363.              else if (s.w<min_cur_size.w)
  364.                 s.w=min_cur_size.w;
  365.              if (!ws && s.w<root_size.w)
  366.                 s.w=root_size.w;
  367.              /*}}}  */
  368.            }
  369.           w->s=s;
  370.           ori_assert(w->s.h==s.h && w->s.w==s.w,"single size diff in regop");
  371.           break;
  372.        /*}}}  */
  373.        /*{{{  top-down/left_right*/
  374.        case top_down:
  375.        case left_right:
  376.         { window *w1,*w2;
  377.  
  378.           w1=w->dat.node.w1;
  379.           w2=w->dat.node.w2;
  380.           if (rec_win_op==del)
  381.            /*{{{  maybe delete the current node from window tree*/
  382.            { if (w1->t==single && w1->dat.edge.b==win_buff_arg)
  383.               /*{{{  change bottom/right and top/left*/
  384.               { w2=w1;
  385.                 w1=w->dat.node.w2;
  386.               }
  387.               /*}}}  */
  388.              if (w2->t==single && w2->dat.edge.b==win_buff_arg)
  389.               /*{{{  delete bottom/right node*/
  390.               {
  391.                 /*{{{  store deleted size*/
  392.                 if (w->t==top_down)
  393.                    add_from_delete.h=w2->s.h;
  394.                 else
  395.                    add_from_delete.w=w2->s.w;
  396.                 /*}}}  */
  397.                 /*{{{  handle number of splitts*/
  398.                 if (w->t==top_down)
  399.                    splitt.h--;
  400.                 else
  401.                    splitt.w--;
  402.                 /*}}}  */
  403.                 /*{{{  delete node*/
  404.                 *w = *w1;
  405.                 paket_free(w1);
  406.                 paket_free(w2);
  407.                 /*}}}  */
  408.                 /*{{{  return resized data*/
  409.                 win_buff_arg=0;
  410.                 rec_win_op=resize;
  411.                 s=rec_w_op(w,s,hs,ws);
  412.                 break;
  413.                 /*}}}  */
  414.               }
  415.               /*}}}  */
  416.            }
  417.            /*}}}  */
  418.           /*{{{  handle both parts of the window tree*/
  419.           { win_data s1,s1n,s2,s2n;
  420.             boolean first_current;
  421.  
  422.             for (;;)
  423.              { s1=w1->s;
  424.                s2=w2->s;
  425.                if (w->t==top_down)
  426.                 /*{{{  handle top_down*/
  427.                 {
  428.                   /*{{{  handle top node*/
  429.                   s1n.w=s.w;
  430.                   s1n.h=  ((s1.h+s2.h)==s.h)
  431.                         ? s1.h
  432.                         : (s.h*(s1.h+1))/(s1.h+s2.h+2);
  433.                   s1=rec_w_op(w1,s1n,True,ws);
  434.                   ori_assert(s1.h==w1->s.h,"top-down-heights1 diff in recop");
  435.                   ori_assert(s1.w==w1->s.w,"top-down-widths1 diff in recop");
  436.                   first_current= !(s1.h==s1n.h && s1.w==s1n.w);
  437.                   /*}}}  */
  438.                   /*{{{  handle bottom*/
  439.                   s2n.w=s1.w;
  440.                   if (s1.h==s1n.h)
  441.                      s2n.h=s.h-s1n.h;
  442.                   else if (s1.h==root_size.h)
  443.                      s2n.h=0;
  444.                   else if (s1.h>=s.h)
  445.                    { s2n.h=root_size.h-s1.h;
  446.                      if (hs) s2n.h/=2;
  447.                    }
  448.                   else
  449.                      s2n.h=s.h-s1.h;
  450.                   s2=rec_w_op(w2,s2n,True,ws);
  451.                   ori_assert(s2.h==w2->s.h,"top-down-heights2 diff in recop");
  452.                   ori_assert(s2.w==w2->s.w,"top-down-widths2 diff in recop");
  453.                   /*}}}  */
  454.                   if (s1.w==s2.w && s1.h+s2.h==s.h)
  455.                    /*{{{  this size is ok, so return*/
  456.                    { s.w=s1.w;
  457.                      s.h=s1.h+s2.h;
  458.                      w->s=s;
  459.                      ori_assert(w->s.w==w1->s.w && w->s.w==w2->s.w,"left-right-widths diff in ret-rec-op");
  460.                      ori_assert(w->s.h==w1->s.h+w2->s.h,"left-right-height-sum diff in ret-rec-op");
  461.                      break;
  462.                    }
  463.                    /*}}}  */
  464.                   /*{{{  get new target size for both windows*/
  465.                   if (w==root_window)
  466.                      s=root_size;
  467.                   else
  468.                    { s.w=first_current?s1.w:s2.w;
  469.                      if (hs)
  470.                       { s.h=first_current?s1.h:s2.h;
  471.                         s.h+=(root_size.h-s.h)/2;
  472.                       }
  473.                      else
  474.                         s.h=root_size.h;
  475.                    }
  476.                   w->s=s;
  477.                   /*}}}  */
  478.                   /*{{{  set new top side*/
  479.                   s1n.w=s2.w;
  480.                   s1n.h=s.h-s2.h;
  481.                   /*}}}  */
  482.                 }
  483.                 /*}}}  */
  484.                else
  485.                 /*{{{  handle left_right*/
  486.                 {
  487.                   /*{{{  handle left*/
  488.                   s1n.h=s.h;
  489.                   s1n.w=  ((s1.w+s2.w)==s.w)
  490.                         ? s1.w
  491.                         : (s.w*(s1.w+1))/(s1.w+s2.w+2);
  492.                   s1=rec_w_op(w1,s1n,hs,True);
  493.                   ori_assert(s1.h==w1->s.h,"left-right-heights1 diff in recop");
  494.                   ori_assert(s1.w==w1->s.w,"left-right-widths1 diff in recop");
  495.                   first_current= !(s1.h==s1n.h && s1.w==s1n.w);
  496.                   /*}}}  */
  497.                   /*{{{  handle right*/
  498.                   s2n.h=s1.h;
  499.                   if (s1.w==s1n.w)
  500.                      s2n.w=s.w-s1.w;
  501.                   else if (s1.w==root_size.w)
  502.                      s2n.w=0;
  503.                   else if (s1.w>=s.w)
  504.                    { s2n.w=root_size.w-s1.w;
  505.                      if (ws) s2n.w/=2;
  506.                    }
  507.                   else
  508.                      s2n.w=s.w-s1.w;
  509.                   s2=rec_w_op(w2,s2n,hs,True);
  510.                   ori_assert(s1.h==w1->s.h,"left-right-heights2 diff in recop");
  511.                   ori_assert(s1.w==w1->s.w,"left-right-widths2 diff in recop");
  512.                   /*}}}  */
  513.                   if (s1.h==s2.h && s1.w+s2.w==s.w)
  514.                    /*{{{  this size is ok, so return*/
  515.                    { s.h=s1.h;
  516.                      s.w=s1.w+s2.w;
  517.                      w->s=s;
  518.                      ori_assert(w->s.h==w1->s.h && w->s.h==w2->s.h,"left-right-heights diff in ret-rec-op");
  519.                      ori_assert(w->s.w==w1->s.w+w2->s.w,"left-right-width-sum diff in ret-rec-op");
  520.                      break;
  521.                    }
  522.                    /*}}}  */
  523.                   /*{{{  get new target size for both windows*/
  524.                   if (w==root_window)
  525.                      s=root_size;
  526.                   else
  527.                    { s.h=first_current?s1.h:s2.h;
  528.                      if (ws)
  529.                       { s.w=first_current?s1.w:s2.w;
  530.                         s.w+=(root_size.w-s.w)/2;
  531.                       }
  532.                      else
  533.                         s.w=root_size.w;
  534.                    }
  535.                   w->s=s;
  536.                   /*}}}  */
  537.                   /*{{{  set new left side*/
  538.                   s1n.h=s2.h;
  539.                   s1n.w=s.w-s2.w;
  540.                   /*}}}  */
  541.                 }
  542.                 /*}}}  */
  543.                s1n=rec_w_op(w1,s1n,hs,True);
  544.                ori_assert(s1n.h==w1->s.h && s1n.w==w1->s.w,"inner node second-first failed");
  545.                break;
  546.              }
  547.           }
  548.           /*}}}  */
  549.           break;
  550.         }
  551.        /*}}}  */
  552.      }
  553.     ori_assert(w->s.h==s.h && w->s.w==s.w,"recop failed");
  554.     return(s);
  555.   }
  556.   /*}}}  */
  557.   /*{{{  rec_scr2buff*/
  558.   private void rec_scr2buff(window *w,win_data o)
  559.    {
  560.      if (w->t==single)
  561.       /*{{{  set window data to buff*/
  562.       { buffer_data *b;
  563.  
  564.         b=(buffer_data*)w->dat.edge.b;
  565.         b->scr.win=b->scr.txt_size=w->s;
  566.         if (!var_notitle) b->scr.txt_size.h-=1;
  567.         b->scr.off=o;
  568.         b->scr.clreol=((b->scr.win.w+b->scr.off.w+root_dont_use.w)==screen.w);
  569.         b->scr.bold_stat=(boolean)so;
  570.         if (sg && b->scr.win.w<=2*sg+MIN_SG_TITLE)
  571.            b->scr.bold_stat=False;
  572.       }
  573.       /*}}}  */
  574.      else
  575.       /*{{{  handle inner node*/
  576.       { rec_scr2buff(w->dat.node.w1,o);
  577.         if (w->t==top_down)
  578.            o.h+=w->dat.node.w1->s.h;
  579.         else
  580.            o.w+=w->dat.node.w1->s.w;
  581.         rec_scr2buff(w->dat.node.w2,o);
  582.       }
  583.       /*}}}  */
  584.    }
  585.   /*}}}  */
  586.  
  587.   private boolean window_op(w_op o,buffer_data const * /*const*/ b)
  588.   {
  589.     /*{{{  handle error situations*/
  590.     switch (o)
  591.      {
  592.        /*{{{  h_[t_]splitt maybe use full height*/
  593.        case h_splitt:
  594.        case h_t_splitt:
  595.           if (root_dont_use.h)
  596.            /*{{{  use full height!*/
  597.            { root_dont_use.h=0;
  598.              init_root_window_size();
  599.              window_op(resize,(buffer_data*)0);
  600.            }
  601.            /*}}}  */
  602.           break;
  603.        /*}}}  */
  604.        /*{{{  h_grow       check if possible, maybe dec don't use*/
  605.        case h_grow:
  606.           if (splitt.h)
  607.              break;
  608.           if (!root_dont_use.h)
  609.              return(True);
  610.           root_dont_use.h-=1;
  611.           init_root_window_size();
  612.        dont_use_change:
  613.         { int i;
  614.  
  615.           for (i=0;scr_off;ocl_screen_on(),i++);
  616.           ClrScr();
  617.           for (;i;ocl_screen_off(),i--);
  618.           break;
  619.         }
  620.        /*}}}  */
  621.        /*{{{  h_shrink     check if possible, maybe inc don't use*/
  622.        case h_shrink:
  623.           if (splitt.h)
  624.              break;
  625.           if (root_dont_use.h+min_scr_height>=screen.h)
  626.              return(True);
  627.           root_dont_use.h++;
  628.           init_root_window_size();
  629.           goto dont_use_change;
  630.        /*}}}  */
  631.        /*{{{  w_[l_]splitt maybe use full width*/
  632.        case w_splitt:
  633.        case w_l_splitt:
  634.           if (root_dont_use.w)
  635.            /*{{{  use full width!*/
  636.            { root_dont_use.w=0;
  637.              init_root_window_size();
  638.              window_op(resize,(buffer_data*)0);
  639.            }
  640.            /*}}}  */
  641.           break;
  642.        /*}}}  */
  643.        /*{{{  w_grow       check if possible, maybe dec don't use'*/
  644.        case w_grow:
  645.           if (splitt.w) break;
  646.           if (!root_dont_use.w) return(True);
  647.           root_dont_use.w--;
  648.           init_root_window_size();
  649.           goto dont_use_change;
  650.        /*}}}  */
  651.        /*{{{  w_shrink     check if possible, maybe inc don't use'*/
  652.        case w_shrink:
  653.           if (splitt.w) break;
  654.           if (root_dont_use.w+min_scr_width>=screen.w) return(True);
  655.           root_dont_use.w++;
  656.           init_root_window_size();
  657.           goto dont_use_change;
  658.        /*}}}  */
  659.        /*{{{  del          check if possible*/
  660.        case del:
  661.           if (splitt.w==0 && splitt.h==0)
  662.              return(True);
  663.           else
  664.              break;
  665.        /*}}}  */
  666.        default:
  667.           break;
  668.      }
  669.     /*}}}  */
  670.     /*{{{  set minimum size*/
  671.     min_cur_size.h=((min_scr_height<root_size.h)?min_scr_height:root_size.h);
  672.     min_cur_size.w=((min_scr_width <root_size.w)?min_scr_width :root_size.w);
  673.     /*}}}  */
  674.     /*{{{  do the window operation*/
  675.     for
  676.      ( rec_win_op=o,
  677.        win_buff_arg=b,
  678.        add_from_delete.h=add_from_delete.w=0
  679.      ;
  680.      ; o=resize,
  681.        b=0
  682.      )
  683.      { rec_w_op(root_window,root_size,False,False);
  684.        if (add_from_delete.h==0 && add_from_delete.w==0)
  685.           break;
  686.      }
  687.     /*}}}  */
  688.     /*{{{  store window data in buffers*/
  689.     { win_data off;
  690.  
  691.       off.h=off.w=0;
  692.       rec_scr2buff(root_window,off);
  693.     }
  694.     /*}}}  */
  695.  
  696.     return(False);
  697.   }
  698.   /*}}}  */
  699.   /*{{{  win_layout*/
  700.   /*{{{  rec_win_layout*/
  701.   private boolean rec_win_layout(window * const w,boolean restore)
  702.   {
  703.     switch (w->t)
  704.      {
  705.        case top_down:
  706.        case left_right:
  707.           rec_win_layout(w->dat.node.w1,restore);
  708.           rec_win_layout(w->dat.node.w2,restore);
  709.        case single:
  710.           if (restore)
  711.              w->s=w->saved_s;
  712.           else
  713.              w->saved_s=w->s;
  714.           break;
  715.      }
  716.     return(restore);
  717.   }
  718.   /*}}}  */
  719. #  define win_layout(t) rec_win_layout(root_window,t)
  720.   /*}}}  */
  721.   /*{{{  init_window*/
  722.   private void init_window(buffer_data const * const b)
  723.   {
  724.     init_root_window_size();
  725.     init_buffer.scr.off.h=0;
  726.     init_buffer.scr.off.w=0;
  727.     splitt.h=splitt.w=0;
  728.     if (!(root_window=paket_malloc(sizeof(window))))
  729.        exit_origami(r_mem_full,M_NO_MEMORY);
  730.     root_window->t=single;
  731.     root_window->s=root_size;
  732.     root_window->dat.edge.b=b;
  733.   }
  734.   /*}}}  */
  735. #endif
  736. /*{{{  calc_window*/
  737. private void set_shift_size(void);
  738. #define calc_window() (window_op(resize,(buffer_data*)0),set_shift_size())
  739. /*}}}  */
  740. /*{{{  go_window*/
  741. private boolean go_window(int const no)
  742. {
  743.   if (no<0 || no>=buff_used)
  744.      return(True);
  745.  
  746.   curr_buff=no;
  747.   warn_mult_edit();
  748.   call_number_macro(buff_macro);
  749.  
  750.   return(False);
  751. }
  752. /*}}}  */
  753. /*{{{  splitt_window*/
  754. private void splitt_window
  755.  ( boolean const t_d,
  756.    boolean const rev,
  757.    int const old,
  758.    buffer_data const * const b)
  759. { int c;
  760.  
  761.   c=curr_buff;
  762.   curr_buff=old;
  763.   window_op
  764.    ( rev
  765.       ? (t_d?h_t_splitt:w_l_splitt)
  766.       : (t_d?h_splitt:w_splitt),
  767.      b
  768.    );
  769.   curr_buff=c;
  770. }
  771. /*}}}  */
  772. /*{{{  del_window*/
  773. #define del_window(b) window_op(del,b)
  774. /*}}}  */
  775. /*}}}  */
  776. /*{{{  buffer handling*/
  777. /*{{{  ind2no*/
  778. private int ind2no(int const i)
  779. {
  780.   return((buff_used<=i || i<0)?0:i+1);
  781. }
  782. /*}}}  */
  783. /*{{{  no2ind*/
  784. #define no2ind(i) ((i)-1)
  785. /*}}}  */
  786. /*{{{  set_buff_id*/
  787. private void set_buff_id(void)
  788. { int i;
  789.  
  790.   for (i=buff_used;i--;)
  791.      buffer_list[i]->scr.list_no=ind2no(i);
  792. }
  793. /*}}}  */
  794. /*{{{  set_shift_size*/
  795. private void set_shift_size(void)
  796. { int i;
  797.  
  798.   for (i=buff_used;i--;)
  799.      buffer_list[i]->scr.shift_size=SHIFT_PART(buffer_list[i]->scr.txt_size.w);
  800.   prompt_shift_size=SHIFT_PART(screen.w);
  801. }
  802. /*}}}  */
  803. /*{{{  init_buffers*/
  804. private void init_buffers(void)
  805. {
  806.   curr_buff=0;
  807.   buff_used=1;
  808.   dsp_buff=1;
  809.   bd_buffer= -1;
  810.   set_fold_mark_dsp_length(&(init_buffer.f.str));
  811.   if
  812.    (    !(buffer_list=paket_malloc((b_l_size=B_L_PAKET)*sizeof(buffer_data*)))
  813.      || !(buffer_list[curr_buff]=paket_malloc(sizeof(buffer_data)))
  814.    )
  815.      exit_origami(r_mem_full,M_NO_MEMORY);
  816.   *(buffer_list[curr_buff])=init_buffer;
  817. }
  818. /*}}}  */
  819. /*{{{  new_buffer*/
  820. private void new_buffer(boolean const h_s,boolean const rev)
  821. { buffer_data *bx;
  822.   int sp_buff;
  823.   int i;
  824.  
  825.   sp_buff=curr_buff;
  826.   /*{{{  maybe extend buffer list*/
  827.   if (buff_used==b_l_size)
  828.    { buffer_data **x;
  829.      size_t n;
  830.  
  831.      if (!(x=ori_malloc(n=((b_l_size+B_L_PAKET)*sizeof(buffer_data*)))))
  832.         exit_origami(r_mem_full,M_NO_MEMORY);
  833.      memcpy(x,buffer_list,n);
  834.      paket_free(buffer_list);
  835.      buffer_list=x;
  836.      b_l_size+=B_L_PAKET;
  837.    }
  838.   /*}}}  */
  839.   /*{{{  get new buffer*/
  840.   if (!(bx=ori_malloc(sizeof(buffer_data))))
  841.      exit_origami(r_mem_full,M_NO_MEMORY);
  842.   /*}}}  */
  843.   /*{{{  put in list*/
  844.   for (i=buff_used++;i>curr_buff+1;i--) buffer_list[i]=buffer_list[i-1];
  845.   *(buffer_list[++curr_buff]=bx)=init_buffer;
  846.   bx->scr.id=buff_id_used++;
  847.   /*}}}  */
  848.   splitt_window(h_s,rev,sp_buff,bx);
  849.   if (rev)
  850.    /*{{{  change curr and prev*/
  851.    { bx=buffer_list[curr_buff];
  852.      buffer_list[curr_buff]=buffer_list[curr_buff-1];
  853.      buffer_list[--curr_buff]=bx;
  854.    }
  855.    /*}}}  */
  856.   set_buff_id();
  857. }
  858. /*}}}  */
  859. /*{{{  del_buffer*/
  860. private void del_buffer(void)
  861. { buffer_data *bx=buffer_list[curr_buff];
  862.  
  863.   paket_free(buffer_list[curr_buff]);
  864.   buff_used--;
  865.   /*{{{  shift buffers*/
  866.   { int i;
  867.  
  868.     for (i=curr_buff;i<buff_used;i++) buffer_list[i]=buffer_list[i+1];
  869.   }
  870.   /*}}}  */
  871.   if (curr_buff) curr_buff--;
  872.   del_window(bx);
  873.   set_buff_id();
  874. }
  875. /*}}}  */
  876. /*}}}  */
  877. /*{{{  send me a mail concerning dumped file*/
  878. /*{{{  default mail is no mail*/
  879. #ifndef MAIL_DATA
  880. #  define MAIL_DATA
  881. #  define MAIL_OPEN(b)
  882. #  define MAIL_PUT(s)
  883. #  define MAIL_CLOSE()
  884. #endif
  885. /*}}}  */
  886.  
  887. public void mail_and_dump(int exit_code)
  888. {
  889.   boolean done;
  890.   MAIL_DATA
  891.  
  892.   { int b;
  893.  
  894.     save_bd(buffer_list[curr_buff]);
  895.     for (b=0,done=False;b<buff_used;b++)
  896.      { char const *n;
  897.  
  898.        set_bd(buffer_list[b]);
  899.        if ((n=dump_file()))
  900.         { if (!done)
  901.            { done=True;
  902.  
  903.              MAIL_OPEN((char*)get_msg(M_MAIL_S));
  904.              /*{{{  write mail header with machine name to the mail*/
  905.              {
  906. #              ifndef NO_MAIL
  907.                   struct utsname mach;
  908. #              endif
  909.  
  910.                MAIL_PUT
  911.                 ( (char*)get_msg
  912.                           ( M_MAIL_1,
  913.                             origami_name,
  914.                             (mach.nodename[0]='\0',uname(&mach),mach.nodename),
  915.                             exit_code
  916.                           )
  917.                 );
  918.              }
  919.              /*}}}  */
  920.            }
  921.           MAIL_PUT((char*)get_msg(M_MAIL_2,bd.scr.list_no,(((bd.f.real_tail==bd.f.real_head)?empty_text:get_data(bd.f.real_tail))),n));
  922.         }
  923.      }
  924.   }
  925.   if (done)
  926.    { MAIL_PUT((char*)get_msg(M_MAIL_3));
  927.      MAIL_CLOSE();
  928.    }
  929. }
  930. /*}}}  */
  931. /*{{{  decode_buffer_mouse*/
  932. public int decode_buffer_mouse(int const x, int const y,boolean const m)
  933. {
  934.   int mb;
  935.  
  936.   /*{{{  get click window*/
  937.   for (mb=buff_used-1;;mb--)
  938.    { scr_dat const *s;
  939.      int z1,z2;
  940.  
  941.      if (mb<0)
  942.         break;
  943.      s= &buffer_list[mb]->scr;
  944.      if
  945.       (   (z1=s->win.h) && y>(z2=s->off.h) && y<=z1+z2
  946.        && (z1=s->win.w) && x>(z2=s->off.w) && x<=z1+z2
  947.       )
  948.         break;
  949.    }
  950.   /*}}}  */
  951. # ifdef MOUSY
  952.      if (m)
  953.       /*{{{  decode the position in detail, set vars*/
  954.       { buffer_data bd_save;
  955.         int mx,my,mgy,mo;
  956.  
  957.         if (mb<0)
  958.          /*{{{  menu or status, set positions relativ to area*/
  959.          { mo= (y==message_line)?-2:-1;
  960.            my=y-area_line.h+1;
  961.            mx=x;
  962.          }
  963.          /*}}}  */
  964.         else
  965.          /*{{{  decode the position inside the clicked buffer*/
  966.          {
  967.            /*{{{  save old buffer data and get clicked buffer data*/
  968.            save_bd(&bd_save);
  969.            if (bd_buffer!=mb) set_bd(buffer_list[mb]);
  970.            /*}}}  */
  971.            /*{{{  prepare inside*/
  972.            mo=0;
  973.            /*}}}  */
  974.            /*{{{  set y and mgy, maybe set outside*/
  975.            { int i;
  976.  
  977.              mgy=i=y-bd.scr.cursor.h-bd.scr.off.h;
  978.              /*{{{  move to line, maybe set outside*/
  979.              while (i>0)
  980.               /*{{{  move down*/
  981.               { if (bd.f.current==bd.f.tail) { mo=2; break; }
  982.                 bd.f.current=bd.f.current->next;
  983.                 i--;
  984.               }
  985.               /*}}}  */
  986.              while (i<0)
  987.               /*{{{  move up*/
  988.               { if (bd.f.current->prec==bd.f.head) { mo=2;break; }
  989.                 bd.f.current=bd.f.current->prec;
  990.                 i++;
  991.               }
  992.               /*}}}  */
  993.              /*{{{  if clicked non edit File-fold-braces, outside=1!*/
  994.              if
  995.               (   i==0
  996.                && (!bd.f.entered&&(bd.f.current==bd.f.tail||bd.f.current->prec==bd.f.head))
  997.               ) mo=1;
  998.              /*}}}  */
  999.              /*}}}  */
  1000.              /*{{{  get line no*/
  1001.              my=line_no(bd.f.current,bd.f.real_head);
  1002.              /*}}}  */
  1003.            }
  1004.            /*}}}  */
  1005.            /*{{{  set x*/
  1006.            mx=x-bd.scr.off.w+((bd.scr.cursor.h==y)?bd.scr.cur_shift_w:bd.scr.full_shift_w);
  1007.            /*}}}  */
  1008.            /*{{{  restore buffer data*/
  1009.            set_bd(&bd_save);
  1010.            /*}}}  */
  1011.          }
  1012.          /*}}}  */
  1013.         ocl_var[var_m_buff].v=ind2no(mb);
  1014.         ocl_var[var_m_y].v=my;
  1015.         ocl_var[var_m_gy].v=mgy;
  1016.         ocl_var[var_m_x].v=mx;
  1017.         ocl_var[var_m_out].v=mo;
  1018.       }
  1019.       /*}}}  */
  1020. # endif
  1021.  
  1022.   return(ind2no(mb));
  1023. }
  1024. /*}}}  */
  1025. /*{{{  main_editor_loop*/
  1026. /*{{{  read_buff*/
  1027. public void read_buff(boolean first)
  1028. {
  1029.   set_bd(buffer_list[curr_buff]);
  1030.   if (!first)
  1031.      bd.f.real_head=bd.f.real_tail=bd.f.head=bd.f.tail=0;
  1032.   if ((arg_list && !start_pipe) || (!first && !filearg[0]))
  1033.    /*{{{  read the list of argument files*/
  1034.    { filearg=0;
  1035.      open_arg_list();
  1036.    }
  1037.    /*}}}  */
  1038.   else
  1039.    /*{{{  read file, maybe append pipe*/
  1040.    { create_list();
  1041.      if (bd.f.real_head!=bd.f.real_tail)
  1042.         bd.e.file_no=add_edit_file((char *)get_data(bd.f.real_tail),1,True);
  1043.      if (start_pipe)
  1044.       /*{{{  append stuff, coming from stdin*/
  1045.       { element *x;
  1046.  
  1047.         /*{{{  move to end*/
  1048.         x=bd.f.tail->prec;
  1049.         /*}}}  */
  1050.         /*{{{  read file*/
  1051.         message(get_msg(F_LOADING,"stdin"));
  1052.         bd.f.current=bd.f.tail;
  1053.         insert_file
  1054.          ( (element *)0,
  1055.            bd.f.current->prec,
  1056.            bd.f.current,
  1057.            False,
  1058.            bd.f.real_head,
  1059.            (boolean*)0,
  1060.            (boolean*)0,
  1061.            start_pipe
  1062.          );
  1063.         fclose(start_pipe);
  1064.         start_pipe=0;
  1065.         /*}}}  */
  1066.         if (x->next!=bd.f.tail)
  1067.          /*{{{  move to start of piped text and maybe set file changed*/
  1068.          { bd.m.file_changed_status=changed_once;
  1069.            title_op(CHGTITLE);
  1070.            bd.f.current=x->next;
  1071.          }
  1072.          /*}}}  */
  1073.       }
  1074.       /*}}}  */
  1075.    }
  1076.    /*}}}  */
  1077.   /*{{{  update statusline and window title*/
  1078.   if (auto_save)
  1079.      set_alarm(0,False);
  1080.   ori_assert(bd.scr.cur_shift_w<=LINELEN,"shift-check");
  1081.   title_op(UPDTITLE);
  1082. #  ifdef WINDOW_TITLE_CHANGE
  1083.      wt_buff_id= -1;
  1084. #  endif
  1085.   /*}}}  */
  1086.   /*{{{  show read text*/
  1087.   find_element((startup_line?startup_line:1),bd.scr.txt_size.h/2);
  1088.   startup_line=0;
  1089.   /*}}}  */
  1090.   /*{{{  init OCL-screen-vars*/
  1091.   bd.scr.cursor.w=1;
  1092.   /*}}}  */
  1093.   call_number_macro(auto_macro);
  1094.   arg_list=False;
  1095.   save_bd(buffer_list[curr_buff]);
  1096. }
  1097. /*}}}  */
  1098. /*{{{  call_buffer_loop*/
  1099. private TOKEN call_buffer_loop(TOKEN ch,int buff)
  1100. {
  1101.   bd_buffer=buff;
  1102.   set_bd(buffer_list[buff]);
  1103.   if (bd.scr.win.h && bd.scr.win.w)
  1104.    { ch=buffer_loop(ch,buff==curr_buff);
  1105.      save_bd(buffer_list[buff]);
  1106.    }
  1107.   bd_buffer= -1;
  1108.  
  1109.   return(ch);
  1110. }
  1111. /*}}}  */
  1112.  
  1113. public RETURNS main_editor_loop(void)
  1114. { TOKEN ch;
  1115.  
  1116.   /*{{{  show empty screen with statusline*/
  1117.   set_bd(&init_buffer);
  1118.   bd.scr.win.h=screen.h-1;
  1119.   bd.scr.txt_size.h=bd.scr.win.h-1+var_notitle;
  1120.   bd.scr.txt_size.w=bd.scr.win.w=screen.w;
  1121.   ClrScr();
  1122.   ori_assert(bd.scr.cur_shift_w<=LINELEN,"shift-check");
  1123.   title_op(PRTTITLE);
  1124.   if (show_string(get_copyright(False),False))
  1125.      sleep(1);
  1126.   oflush;
  1127.   save_bd(&init_buffer);
  1128.   /*}}}  */
  1129.   /*{{{  init buffers/windows*/
  1130.   init_buffers();
  1131.   init_window(buffer_list[curr_buff]);
  1132.   calc_window();
  1133.   /*}}}  */
  1134.   read_buff(True);
  1135.   set_buff_id();
  1136.   warn_mult_edit();
  1137.   running=True;
  1138.   for (;;)
  1139.    { ocl_var[var_us_buff].v=buff_used;
  1140.      switch (ch=call_buffer_loop(O_NOP,curr_buff))
  1141.       {
  1142.         /*{{{  O_DESCRIBE_BINDINGS/O_HELP*/
  1143.         case O_DESCRIBE_BINDINGS:
  1144.         case O_HELP:
  1145.            set_bd(buffer_list[curr_buff]);
  1146.            bd.scr.win.h=screen.h-1-root_dont_use.h;
  1147.            bd.scr.txt_size.h=bd.scr.win.h-1+var_notitle;
  1148.            bd.scr.txt_size.w=screen.w-root_dont_use.w;
  1149.            bd.scr.off.h=0;
  1150.            bd.scr.off.w=0;
  1151.            help(ch==O_HELP);
  1152.            goto do_flush;
  1153.         /*}}}  */
  1154.         /*{{{  O_TITLE_HIDE*/
  1155.         case O_TITLE_HIDE:
  1156.            if (var_notitle) continue;
  1157.            var_notitle=1;
  1158.            goto do_flush;
  1159.         /*}}}  */
  1160.         /*{{{  O_TITLE_SHOW*/
  1161.         case O_TITLE_SHOW:
  1162.            if (!var_notitle) continue;
  1163.            var_notitle=0;
  1164.            goto do_flush;
  1165.         /*}}}  */
  1166.         /*{{{  O_DSP*/
  1167.         case O_DSP:
  1168.          { boolean loop=ocl_var[var_mod_beh].v==0;
  1169.            int cmd_type;
  1170.  
  1171.            /*{{{  set all cursor to col 1*/
  1172.            { int i;
  1173.  
  1174.              for (i=buff_used-1;i>=0;i--)
  1175.                 buffer_list[i]->scr.cursor.w = 1;
  1176.            }
  1177.            /*}}}  */
  1178.            ocl_var[var_ocl_arg].v=
  1179.               ((dsp.ctrl==ictrl_dsp) ?  1 : 0)
  1180.             + (numb_dsp(dsp.ctrl)    ?  2 : 0)
  1181.             + (numb_dsp(dsp.high)    ?  4 : 0)
  1182.             + (numb_dsp(dsp.norm)    ?  8 : 0)
  1183.             + ((dsp.base==oct_dsp)   ? 16 : 0)
  1184.             + ((dsp.base==dec_dsp)   ? 32 : 0)
  1185.             + dsp.tab_size*64;
  1186.            cmd_type=menu_item(get_msg(M_DSP,dsp.tab_size),0,False,True);
  1187.            switch (cmd_type)
  1188.             {
  1189.               /*{{{  0 -> quit*/
  1190.               case 0:
  1191.                  no_message();
  1192.                  break;
  1193.               /*}}}  */
  1194.               /*{{{  7 -> tab width: prompt for*/
  1195.               case 7:
  1196.                {
  1197. #                define NBSIZE ((sizeof(int)<<2)+1)
  1198.                  unsigned char tab_txt[NBSIZE];
  1199.  
  1200.                  s_readprompt(tab_txt,get_msg(M_TABSIZE),NBSIZE-1,misc_history);
  1201.                  if (!aborted)
  1202.                   { cmd_type= -atoi((char*)tab_txt);
  1203.                     if (cmd_type>0)
  1204.                        cmd_type=0;
  1205.                   }
  1206.                  else
  1207.               default:
  1208.                     cmd_type='c';
  1209.                  goto chg_mode;
  1210.                }
  1211.               /*}}}  */
  1212.               /*{{{  1-6,8-10 pass code*/
  1213.               case 1:
  1214.               case 2:
  1215.               case 3:
  1216.               case 4:
  1217.               case 5:
  1218.               case 6:
  1219.               case 8:
  1220.               case 9:
  1221.               case 10:
  1222.                  cmd_type="odhmin p8a"[cmd_type-1];
  1223.                  goto chg_mode;
  1224.               /*}}}  */
  1225.               chg_mode:
  1226.                 chg_dsp_type(cmd_type);
  1227.                 /*{{{  calculate the size of the fold mark displays*/
  1228.                 { int i;
  1229.  
  1230.                   for (i=buff_used-1;i>=0;i--)
  1231.                      set_fold_mark_dsp_length(&(buffer_list[i]->f.str));
  1232.                 }
  1233.                 /*}}}  */
  1234.                 if (loop)
  1235.                  /*{{{  push macro to stay in loop*/
  1236.                  { static TOKEN looping[]={ O_DSP,M_END_MACRO };
  1237.  
  1238.                    push_macro(looping);
  1239.                  }
  1240.                  /*}}}  */
  1241.                 else
  1242.                    no_message();
  1243.                 goto do_flush;
  1244.             }
  1245.            break;
  1246.          }
  1247.         /*}}}  */
  1248.         /*{{{  O_GROW_BUFFER:*/
  1249.         case O_GROW_BUFFER:
  1250.            if (window_op(h_grow,(buffer_data*)0))
  1251.               goto buffs_size_failed;
  1252.            goto do_flush;
  1253.         /*}}}  */
  1254.         /*{{{  O_SHRINK_BUFFER:*/
  1255.         case O_SHRINK_BUFFER:
  1256.            if (window_op(h_shrink,(buffer_data*)0))
  1257.               goto buffs_size_failed;
  1258.            goto do_flush;
  1259.         /*}}}  */
  1260.         /*{{{  O_GROW_W_BUFFER:*/
  1261.         case O_GROW_W_BUFFER:
  1262.            if (window_op(w_grow,(buffer_data*)0))
  1263.               goto buffs_size_failed;
  1264.            goto do_flush;
  1265.         /*}}}  */
  1266.         /*{{{  O_SHRINK_W_BUFFER:*/
  1267.         case O_SHRINK_W_BUFFER:
  1268.            if (window_op(w_shrink,(buffer_data*)0))
  1269.             { buffs_size_failed:
  1270.               msg_message(M_FAILED);
  1271.               break;
  1272.             }
  1273.            goto do_flush;
  1274.         /*}}}  */
  1275.         /*{{{  M_GO_BUFFER*/
  1276.         case M_GO_BUFFER:
  1277.          { int n;
  1278.            int t;
  1279.  
  1280.            t=get_arg("go-biff-type");
  1281.            n=ocl_var[get_arg("go-buff-no")].v;
  1282.            if (t==1)
  1283.             /*{{{  use id as target*/
  1284.             { int j;
  1285.  
  1286.               for (j=0;;j++)
  1287.                  if (j==buff_used)
  1288.                      goto no_more_buffs;
  1289.                  else if (n==buffer_list[j]->scr.id)
  1290.                   { n=j;
  1291.                     break;
  1292.                   }
  1293.             }
  1294.             /*}}}  */
  1295.            else
  1296.             /*{{{  use list no as target*/
  1297.             n=no2ind(n);
  1298.             /*}}}  */
  1299.            if (go_window(n))
  1300.             /*{{{  error report: no more buffers*/
  1301.             { no_more_buffs:
  1302.               msg_message(M_NO_BUFFERS);
  1303.               break;
  1304.             }
  1305.             /*}}}  */
  1306.            goto do_flush;
  1307.          }
  1308.         /*}}}  */
  1309.         /*{{{  O_OPEN_[LIST_][W_]BUFFER*/
  1310.         case O_OPEN_BUFFER:
  1311.         case O_OPEN_W_BUFFER:
  1312.         case O_OPEN_LIST_BUFFER:
  1313.         case O_OPEN_LIST_W_BUFFER:
  1314.          { boolean rev;
  1315.  
  1316.            rev=(ocl_var[var_mod_beh].v>0)||(ocl_var[var_mod_beh].v==-1);
  1317.            /*{{{  set filearg to new filename*/
  1318.            if (ch==O_OPEN_LIST_BUFFER || ch==O_OPEN_LIST_W_BUFFER)
  1319.              /*{{{  prompt for number and decode it*/
  1320.              { s_readprompt(print_buffer,get_msg(M_FILEPO),15,misc_history);
  1321.                if (aborted) break;
  1322.                filearg=fileno2name(atoi((char*)print_buffer));
  1323.              }
  1324.              /*}}}  */
  1325.            else
  1326. #           ifdef OS_NULL_DEVICE
  1327.            if (ocl_var[var_mod_beh].v<0)
  1328.               filearg=(unsigned char*)OS_NULL_DEVICE;
  1329.            else
  1330. #           endif
  1331.             /*{{{  prompt for filename*/
  1332.             { if ((!(*fileprompt(print_buffer))) || aborted) break;
  1333.               filearg=print_buffer;
  1334.             }
  1335.             /*}}}  */
  1336.            /*}}}  */
  1337.            new_buffer((ch==O_OPEN_BUFFER || ch==O_OPEN_LIST_BUFFER),rev);
  1338.            read_buff(False);
  1339.            warn_mult_edit();
  1340.            call_number_macro(buff_macro);
  1341.            goto do_flush;
  1342.          }
  1343.         /*}}}  */
  1344.         /*{{{  O_A_AUTO_SAVE*/
  1345.         case O_A_AUTO_SAVE:
  1346.            if (ocl_var[var_mod_beh].v>0)
  1347.             /*{{{  seconds from modify-behaviour*/
  1348.             { if (!auto_save)
  1349.                  title_op(CHGTITLE);
  1350.               auto_save = True;
  1351.               set_alarm(ocl_var[var_mod_beh].v,True);
  1352.             }
  1353.             /*}}}  */
  1354.            else
  1355.             /*{{{  prompts for minute*/
  1356.             { unsigned char time[12];
  1357.  
  1358.               s_readprompt(time, (unsigned char*)"auto-save-interval", 10,no_history);
  1359.               if (!aborted) {
  1360.                 if (!auto_save)
  1361.                    title_op(CHGTITLE);
  1362.                 auto_save = True;
  1363.                 set_alarm(atoi((char *)time),False);
  1364.               }
  1365.             }
  1366.             /*}}}  */
  1367.            break;
  1368.         /*}}}  */
  1369.         /*{{{  O_D_AUTO_SAVE*/
  1370.         case O_D_AUTO_SAVE:
  1371.            ocl_var[var_ocl_arg].v=auto_save?alarm_time:0;
  1372.            if (auto_save)
  1373.               title_op(CHGTITLE);
  1374.            auto_save = False;
  1375.            reset_alarm();
  1376.            break;
  1377.         /*}}}  */
  1378.         /*{{{  O_AUTO_SAVE*/
  1379.         case O_AUTO_SAVE:
  1380.            set_alarm(0,False);
  1381.            if (salarm_macro)
  1382.             { call_number_macro(salarm_macro);
  1383.               break;
  1384.             }
  1385.            else
  1386.               goto do_for_all;
  1387.         /*}}}  */
  1388.         /*{{{  O_[A|D]_NOPARSE*/
  1389.         case O_D_NOPARSE:
  1390.         case O_A_NOPARSE:
  1391.            set_bd(buffer_list[curr_buff]);
  1392.            ocl_var[var_ocl_arg].v=bd.e.fold_in?0:1;
  1393.            init_buffer.e.fold_in=bd.e.fold_in=(ch==O_A_NOPARSE);
  1394.            title_op(CHGTITLE);
  1395.            save_bd(buffer_list[curr_buff]);
  1396.            break;
  1397.         /*}}}  */
  1398.         /*{{{  QUIT's*/
  1399.         { RETURNS exit_code;
  1400.  
  1401.         case M_FINISH:
  1402.            exit_code=ocl_var[get_arg("exit")].v;
  1403.            prompt_string(print_buffer);
  1404.         case O_FINISH:
  1405.         case O_QUIT:
  1406.            if (buff_used>1)
  1407.             /*{{{  delete current buffer*/
  1408.             { set_bd(buffer_list[curr_buff]);
  1409.               delete_list(bd.f.real_head, bd.f.real_tail);
  1410.               set_0_data(bd.f.real_tail);
  1411.               set_linetyp(*bd.f.real_tail,NOT_FOLD);
  1412.               proc_dispose(bd.f.real_tail);
  1413.               set_0_data(bd.f.real_head);
  1414.               set_linetyp(*bd.f.real_head,NOT_FOLD);
  1415.               proc_dispose(bd.f.real_head);
  1416.               del_buffer();
  1417.               warn_mult_edit();
  1418.               call_number_macro(buff_macro);
  1419.               goto do_flush;
  1420.             }
  1421.             /*}}}  */
  1422.            else
  1423.             /*{{{  exit the editor*/
  1424.             { if (ch!=M_FINISH)
  1425.                { exit_code=(bd.m.file_changed_status!=unchanged_file)?r_file_nok:r_ok;
  1426.                  print_buffer[0]='\0';
  1427.                }
  1428.               return(exit_code);
  1429.             }
  1430.             /*}}}  */
  1431.         }
  1432.         /*}}}  */
  1433.         /*{{{  M_LAYOUT*/
  1434.         case M_LAYOUT:
  1435.            if (win_layout(get_arg("layout-command")))
  1436.               goto do_flush;
  1437.            break;
  1438.         /*}}}  */
  1439.         /*{{{  O_FLUSH*/
  1440.         case O_FLUSH:
  1441.          { int x=executing_macro?ocl_var[get_arg("flush-line")].v:0;
  1442.  
  1443.            if (x>=1 || x<=buffer_list[curr_buff]->scr.txt_size.h)
  1444.               buffer_list[curr_buff]->scr.cursor.h=x;
  1445.         do_flush:
  1446.            calc_window();
  1447.            ch=O_FLUSH;
  1448.            restore_area();
  1449.            goto do_for_all;
  1450.          }
  1451.         /*}}}  */
  1452.         /*{{{  O_REFRESH*/
  1453.         case O_REFRESH:
  1454.            if (get_terminal_capability())
  1455.               return(r_init_err);
  1456.            if (ocl_var[var_mod_beh].v==0)
  1457.               B_invalid();
  1458.            /*{{{  window?*/
  1459. #           if defined(SIGWINCH) || defined(MGR)
  1460.               if (win_changed && !scr_off)
  1461.                { win_changed = False;
  1462.                  verbose_msg_message(M_WIN_CHANGED);
  1463.                }
  1464. #           endif
  1465.            /*}}}  */
  1466.            init_root_window_size();
  1467.            calc_window();
  1468.            restore_area();
  1469.            ch=O_REFRESH;
  1470.         do_for_all:
  1471.           /*{{{  try to do ch in all buffers*/
  1472.           { int i;
  1473.  
  1474.             for (i=buff_used-1;i>=0;i--)
  1475.                call_buffer_loop(ch,i);
  1476.             continue;
  1477.           }
  1478.           /*}}}  */
  1479.         /*}}}  */
  1480.         default:
  1481.            continue;
  1482.       }
  1483.    }
  1484. }
  1485. /*}}}  */
  1486.